﻿using ArtMath.Attribute;
using ArtMath.Component.Point;
using ArtMath.Core.Data;
using ArtMath.Core.Helper;
using ArtMath.Data;
using ArtMath.Resource;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArtMath.Component.ConicalSection
{
    /// <summary>
    /// 约束双曲线
    /// </summary>
    [Serializable]
    public class ConstrainedHyperbola : HyperbolaBase
    {
        PadStringX a, b;
        AngleStringX focusAngle;
        public ConstrainedHyperbola(SketchPad pad, string name, string a, string b, string rotate, bool addToList = true) : base(pad, name, ToolTypeName.yssqx, addToList)
        {
            InPoints = new PointBase[1];
            StrRealAxisHalfLength = new PadStringX(Pad, a);
            RealAxisHalfLength = StrRealAxisHalfLength.Value;
            StrImaginaryAxisHalfLength = new PadStringX(Pad, b);
            ImaginaryAxisHalfLength = StrImaginaryAxisHalfLength.Value;
            StrFocusAngle = new AngleStringX(Pad, rotate);
            FocusAngle = StrFocusAngle.RadValue;
        }
        public override PointD NewCenter
        {
            get
            {
                return CenterPoint.NewXY;
            }
        }
        public override PointD NewPCenter
        {
            get
            {
                return CenterPoint.NewPxy;
            }
        }
        public override void SetPoint(int index, PointBase value)
        {
            base.SetPoint(index, value);
            if (value != null)
            {
                switch (index)
                {
                    case 0:
                        ske.Center = value.ToPointD();
                        pske.Center = value.Pxy;
                        break;
                }
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName(null, "Hyperbola", "Center")]
        public PointBase CenterPoint
        {
            get { return InPoints[0]; }
            set { SetPoint(0, value); }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("RealAxisHalfLength")]
        public PadStringX StrRealAxisHalfLength
        {
            get { return a; }
            set
            {
                if (a is object)
                {
                    a.ParametersValueChanging -= RealAxisHalfLength_ParametersValueChanging;
                    a.ParametersValueChanged -= RealAxisHalfLength_ParametersValueChanged;
                    a.ExpressionSetting -= RealAxisHalfLength_ExpressionSetting;
                    a.ExpressionSet -= RealAxisHalfLength_ExpressionSet;
                }
                a = value;
                if (a is object)
                {
                    a.ParametersValueChanging += RealAxisHalfLength_ParametersValueChanging;
                    a.ParametersValueChanged += RealAxisHalfLength_ParametersValueChanged;
                    a.ExpressionSetting += RealAxisHalfLength_ExpressionSetting;
                    a.ExpressionSet += RealAxisHalfLength_ExpressionSet;
                }
            }
        }

        void RealAxisHalfLength_ExpressionSet(StringX sender, ExpressionSetEventArgs e)
        {
            CenterPoint.TempMoveLock = true;
            if (Pad.MoveObject_DoMouseMove(this, PointD.Empty))
            {
                ComponentChanged(this);
            }
            else
            {
                Pad.ShowMessage(string.Format(Resources.Translate("FailModify"), OfTranslator("RealAxisHalfLength")), MessageType.Error);
                StrRealAxisHalfLength.SetExpression(e.OldExpression, false);
            }
            Pad.MoveObject_DoMouseUp(this);
            CenterPoint.TempMoveLock = false;
        }

        void RealAxisHalfLength_ExpressionSetting(StringX sender)
        {
            CenterPoint.TempMoveLock = true;
            Pad.MoveObject_DoMouseDown(this);
            CenterPoint.TempMoveLock = false;
        }

        void RealAxisHalfLength_ParametersValueChanged(DocStringX sender, ParametersValueChangedEventArgs e)
        {
            CenterPoint.TempMoveLock = true;
            if (Pad.MoveObject_DoMouseMove(this, PointD.Empty))
            {
                ComponentChanged(this);
            }
            else
            {

            }
            Pad.MoveObject_DoMouseUp(this);
            CenterPoint.TempMoveLock = false;
        }

        void RealAxisHalfLength_ParametersValueChanging(DocStringX sender)
        {
            CenterPoint.TempMoveLock = true;
            Pad.MoveObject_DoMouseDown(this);
            CenterPoint.TempMoveLock = false;
        }
        public override double NewRealAxisHalfLength
        {
            get
            {
                return StrRealAxisHalfLength.Value;
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("ImaginaryAxisHalfLength")]
        public PadStringX StrImaginaryAxisHalfLength
        {
            get { return b; }
            set
            {
                if (b is object)
                {
                    b.ParametersValueChanging -= ImaginaryAxisHalfLength_ParametersValueChanging;
                    b.ParametersValueChanged -= ImaginaryAxisHalfLength_ParametersValueChanged;
                    b.ExpressionSetting -= ImaginaryAxisHalfLength_ExpressionSetting;
                    b.ExpressionSet -= ImaginaryAxisHalfLength_ExpressionSet;
                }
                b = value;
                if (b is object)
                {
                    b.ParametersValueChanging += ImaginaryAxisHalfLength_ParametersValueChanging;
                    b.ParametersValueChanged += ImaginaryAxisHalfLength_ParametersValueChanged;
                    b.ExpressionSetting += ImaginaryAxisHalfLength_ExpressionSetting;
                    b.ExpressionSet += ImaginaryAxisHalfLength_ExpressionSet;
                }
            }
        }

        void ImaginaryAxisHalfLength_ExpressionSet(StringX sender, ExpressionSetEventArgs e)
        {
            CenterPoint.TempMoveLock = true;
            if (Pad.MoveObject_DoMouseMove(this, PointD.Empty))
            {
                ComponentChanged(this);
            }
            else
            {
                Pad.ShowMessage(string.Format(Resources.Translate("FailModify"), OfTranslator("ImaginaryAxisHalfLength")), MessageType.Error);
                StrImaginaryAxisHalfLength.SetExpression(e.OldExpression, false);
            }
            Pad.MoveObject_DoMouseUp(this);
            CenterPoint.TempMoveLock = false;
        }

        void ImaginaryAxisHalfLength_ExpressionSetting(StringX sender)
        {
            CenterPoint.TempMoveLock = true;
            Pad.MoveObject_DoMouseDown(this);
            CenterPoint.TempMoveLock = false;
        }

        void ImaginaryAxisHalfLength_ParametersValueChanged(DocStringX sender, ParametersValueChangedEventArgs e)
        {
            CenterPoint.TempMoveLock = true;
            if (Pad.MoveObject_DoMouseMove(this, PointD.Empty))
            {
                ComponentChanged(this);
            }
            else
            {

            }
            Pad.MoveObject_DoMouseUp(this);
            CenterPoint.TempMoveLock = false;
        }

        void ImaginaryAxisHalfLength_ParametersValueChanging(DocStringX sender)
        {
            CenterPoint.TempMoveLock = true;
            Pad.MoveObject_DoMouseDown(this);
            CenterPoint.TempMoveLock = false;
        }
        public override double NewImaginaryAxisHalfLength
        {
            get
            {
                return StrImaginaryAxisHalfLength.Value;
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("DirectedAngle")]
        public AngleStringX StrFocusAngle
        {
            get { return focusAngle; }
            set
            {
                if (focusAngle is object)
                {
                    focusAngle.ParametersValueChanging -= FocusAngle_ParametersValueChanging;
                    focusAngle.ParametersValueChanged -= FocusAngle_ParametersValueChanged;
                    focusAngle.ExpressionSetting -= FocusAngle_ExpressionSetting;
                    focusAngle.ExpressionSet -= FocusAngle_ExpressionSet;
                }
                focusAngle = value;
                if (focusAngle is object)
                {
                    focusAngle.ParametersValueChanging += FocusAngle_ParametersValueChanging;
                    focusAngle.ParametersValueChanged += FocusAngle_ParametersValueChanged;
                    focusAngle.ExpressionSetting += FocusAngle_ExpressionSetting;
                    focusAngle.ExpressionSet += FocusAngle_ExpressionSet;
                }
            }
        }

        void FocusAngle_ExpressionSet(StringX sender, ExpressionSetEventArgs e)
        {
            CenterPoint.TempMoveLock = true;
            if (Pad.MoveObject_DoMouseMove(this, PointD.Empty))
            {
                ComponentChanged(this);
            }
            else
            {
                Pad.ShowMessage(string.Format(Resources.Translate("FailModify"), OfTranslator("DirectedAngle")), MessageType.Error);
                StrFocusAngle.SetExpression(e.OldExpression, false);
            }
            Pad.MoveObject_DoMouseUp(this);
            CenterPoint.TempMoveLock = false;
        }

        void FocusAngle_ExpressionSetting(StringX sender)
        {
            CenterPoint.TempMoveLock = true;
            Pad.MoveObject_DoMouseDown(this);
            CenterPoint.TempMoveLock = false;
        }

        void FocusAngle_ParametersValueChanged(DocStringX sender, ParametersValueChangedEventArgs e)
        {
            CenterPoint.TempMoveLock = true;
            if (Pad.MoveObject_DoMouseMove(this, PointD.Empty))
            {
                ComponentChanged(this);
            }
            else
            {

            }
            Pad.MoveObject_DoMouseUp(this);
            CenterPoint.TempMoveLock = false;
        }

        void FocusAngle_ParametersValueChanging(DocStringX sender)
        {
            CenterPoint.TempMoveLock = true;
            Pad.MoveObject_DoMouseDown(this);
            CenterPoint.TempMoveLock = false;
        }
        public override double NewFocusAngle
        {
            get
            {
                return StrFocusAngle.RadValue;
            }
        }
        public override void CreateComponents()
        {
            if (CenterPoint == null)
            {
                CenterPoint = Pad.CreatePoint(Resources.JoinLocalizedString("Hyperbola", "Center"), SpareCoordinate_);
                SpareCoordinate_ = CenterPoint.Pxy;
                Pad.TrackObj = this;
                base.CreateComponents();
            }
        }
        public override object CopyAndPaste(SketchPad pad)
        {
            ConstrainedHyperbola ch = new ConstrainedHyperbola(pad, Utility.GetNextAvailableName(Name, pad.CheckObjectNameExist), StrRealAxisHalfLength.DirectExpression, StrImaginaryAxisHalfLength.DirectExpression, StrFocusAngle.DirectExpression, LayerItem != null);
            afterNewCopy(ch);
            return ch;
        }
    }
}
